#!/usr/bin/env python3

# EEPROM Programmer - Module eeprom
#
# Module that contains the class Programmer which is used by the other scripts.
# Programmer is inheritated from the class Serial of the pySerial module. It
# provides the basic functions for communicating with the EEPROM programmer.
#
# pySerial needs to be installed
#
# 2020 by Stefan Wagner

import traceback
from serial import Serial
from serial.tools.list_ports import comports

pid = '1a86'
hid = '7523'
chipTitle = 'EEPROM28'


class Programmer(Serial):
    def __init__(self):
        super().__init__(baudrate=115200, timeout = 1, write_timeout = 1)
        self.identify()

    def identify(self):
        for p in comports():
            if pid and hid in p.hwid:
                self.port = p.device
                print("使用ch340连接:{}".format(p.device))

                try:
                    self.open()
                except:
                    print("打开端口异常:{}".format(p.device))
                    continue

                try:
                    if self.is_open:
                        self.sendcommand('i')
                        data = self.getline()
                        self.sendcommand('i')
                        data = self.getline()
                        print('data:{}'.format(data))
                    else:
                        print('端口打开异常')
                        return -1
                except:
                    self.close()
                    continue

                if data.startswith(chipTitle):
                    self.readline()
                    return 1
                else:
                    self.close()
                    # 版本不匹配
                    return -9999
            else:
                print("使用非ch340连接")


    def sendcommand(self, cmd, chip='', startAddr=-1, endAddr=-1):
        cmd += ' %6s' % chip
        if startAddr >= 0:
            cmd += '  %04x' % startAddr
            if endAddr >= 0:
                cmd += '  %04x' % endAddr
        self.write((cmd + '\n').encode())
        print("输出命令:{}".format(cmd))


    def getline(self):
        res = self.readline().decode()
        if res.endswith("\n"):
            res = res[0:len(res)-1]
        return res


    def confirmation(self):
        self.sendcommand ('t')
        return (self.getline().startswith('Ready'))


    def getversion(self):
        self.sendcommand ('v')
        version = self.getline()
        self.readline()
        return version


    def unlock(self):
        self.sendcommand('u')
        return self.confirmation()


    def lock(self):
        self.sendcommand('l')
        return self.confirmation()


if __name__ == '__main__':
    eeprom = Programmer()
    if not eeprom.is_open:
        print('ERROR: EEPROM Programmer not found')
        exit(1)

    print('EEPROM Programmer found on ' + eeprom.port)
    print('Firmware version: ' + eeprom.getversion())
